package oop.ex2.filters;



import oop.ex2.filters.exceptions.FilterDataException;

/**
 * Abstract class of wild card filters.
 */
abstract class WildCardFilter extends Filter {
	//***********************************************************************
	//  Finals :                                                            *
	//***********************************************************************
	protected static final int NO_WILDCARD = 0;
	protected static final int BEGGINING = 1;
	protected static final int END = 2;
	protected static final int BEGGINING_AND_END = 3;
	protected static final String WILD_CARD = "*";
	//***********************************************************************
	//  Methods :                                                           *
	//***********************************************************************
	
	/**
	 * Constructs a new wild card filter.	 
	 */
	public WildCardFilter(){
		super();
	}
	/**
     * Checks the location of the wild card within a string.
     * @return The location of the wild card.
     */
    protected int wildCardLocation(){
    	if (!(getData().contains(WILD_CARD))){
    		return NO_WILDCARD;
    	}
    	else if (getData().startsWith(WILD_CARD) && 
    	        getData().endsWith(WILD_CARD)){
     			return BEGGINING_AND_END;    			
    		}
		else if ( getData().startsWith( WILD_CARD ) ){
			return END;
    	}
    	else {
    		return BEGGINING;
    	}
    }
    /**
     * Checks if a given string ends with another given string.
     * @param checked The checked string.
     * @param endString The wished end of the checked string.
     * @return True if the checked string ends with the end string,
     * false otherwise.
     */
    protected boolean stringEnd(String checked, String endString){
        if ( endString.length()-1 > checked.length() ) {
            return false;
        }
        return (checked.endsWith(endString.replace(WILD_CARD, "")));

    }
    /**
     * Checks if a given string starts with another given string.
     * @param checked The checked string.
     * @param startString The wished end of the checked string.
     * @return True if the checked string starts with the end string,
     * false otherwise.
     */
    protected boolean stringStart(String checked, String startString){
        if( startString.length()-1 > checked.length() ) {
            return false;
        }
        return (checked.startsWith(startString.replace(WILD_CARD, "")));
    }
     /**
     * Calculate and set the condition status of the filter.
     */
    public void calculate(){
    	if (getFileData() == null){
    		_condition = STATUS.FALSE;
    		return;
    	}
    	switch(wildCardLocation()){
    	case NO_WILDCARD: if (checkNoWildCard()){
    		_condition = STATUS.TRUE;
    	}
    	else{
    		_condition = STATUS.FALSE;
    	}
    	break;
    	case END: if (checkEndWildCard()){
    	    _condition = STATUS.TRUE;
    	}
    	else{
    		_condition = STATUS.FALSE;
    	}
    	break;
    	case BEGGINING: if (checkBeginningWildCard()){
    		_condition = STATUS.TRUE;
    	}
    	else{
    		_condition = STATUS.FALSE;
    	}
    	break;
    	case BEGGINING_AND_END: if (checkBegininngAndEndWildCard()){
    		_condition = STATUS.TRUE;
    	}
    	else{
    		_condition = STATUS.FALSE;
    	}
    	break;
    	}
    }
    /**
     * Checks expressions with no wild cards.
     * @return True if the expression is exactly as the filter value,
     *  false otherwise. 
     */
    protected boolean checkNoWildCard(){
    	String str[] = getFileData();
    	for( int i=0; i<str.length; i++) {
    	    if ( str[i].equals(getData() ) ) {
    	        return true;
    	    }
    	}
    	return false;
    }
    /**
     * Checks expressions with wild cards at the beginning 
     * of the expression.
     * @return True if the expression matches the filter value,
     * false otherwise. 
     */
    protected boolean checkBeginningWildCard(){
    	String str[] = getFileData();
    	for ( int i=0; i<str.length; i++ ){
    	    if ( stringStart(str[i],getData()) ){
    	        return true;
    	    }
    	}
    	return false;
    }
    /**
     * Checks expressions with wild cards at the end of the expression.
     * @return True if the expression matches the filter value,
     * false otherwise. 
     */
    protected boolean checkEndWildCard(){
        String str[] = getFileData();
        for ( int i=0; i<str.length; i++ ){
            if ( stringEnd(str[i],getData())){
                return true;
            }
        }
        return false;
   }
    /**
     * Checks expressions with wild cards at the beginning and the end
     * of the expression.
     * @return True if the expression matches the filter value,
     * false otherwise. 
     */
    protected boolean checkBegininngAndEndWildCard(){
    	String str[] = getFileData();
    	if ( str == null ) {
    	    return false;
    	}
    	String path="";
    	for ( int i=0; i<str.length; i++ ) {
    	    path+=str[i];
    	    if (path.contains(getData().replaceAll("\\*", "")) ){
    	        return true;
    	    }
    	}
    	return false;
    }
    public Filter clone() {
        return new FileNameWildCardFilter();
    }
    /**
     * Returns File's relevant data.
     * @return File's relevant data, or null if the file doesn't
     * hold the filter
     * condition (Check directory on non directory file).
     */
    public abstract String[] getFileData();
    /**
     * Returns filter's data.
     * @throws FilterDataException In case of wrong filter parameters. 
     */
    public void setData(String data) throws FilterDataException{
    	_data = data;
    }
}
